﻿using Daemon.Common.Extensions;
using Daemon.Middleware;
using Daemon.Model;
using JinianNet.JNTemplate;
using Microsoft.AspNetCore.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Daemon.Common.Generator
{
	public class SelectComponentGenerator : ComponentGenerator
	{
		public override string WidgetTypeName => "Select";

		public override ComponentResponse DoGenerate(Component component)
		{
			var response = new ComponentResponse();
			StringBuilder strResult = new StringBuilder();
			var context = ServiceLocator.Resolve<ApiDBContent>();
			var datasourceConfig = context.DatasourceConfig.First(r => r.Id == component.DatasourceId);
			#region 
			strResult.Append(GenerateSelectHtml(component, datasourceConfig));
			response.ComponentHtml = strResult.ToString();
			if (component.DatasourceId.HasValue)
			{
				var (variableList, functionList) = GenerateDatasource(component, datasourceConfig);
				response.VariableList = variableList;
				response.FunctionList = functionList;
			}
			else
			{
				response.VariableList = GenerateVariable(component);
			}
			#endregion
			return response;
		}

		public override List<string> GenerateVariable(Component component)
		{
			if (component.DatasourceId.HasValue)
			{
				return new List<string>();
			}

			#region 
			var selectOptions = new StringBuilder(" const selectOption:any[] = [");
			component.Props.Options.ForEach(option =>
			{
				if (int.TryParse(option.Value, out int _))
				{
					selectOptions.Append($"{{value:{option.Value},label:'{option.Label}'}}");
				}
				else
				{
					selectOptions.Append($"{{value:'{option.Value}',label:'{option.Label}}}'");
				}
			});
			selectOptions.Append("]");
			var result = new List<string>();
			result.Add(selectOptions.ToString());
			#endregion
			return result;
		}

		private string GenerateSelectHtml(Component component, DatasourceConfig config)
		{
			StringBuilder strResult = new StringBuilder();
			var datasourceName = component.DatasourceId.HasValue ? config.Name.CapitalizeLower() : "selectOption";
			strResult.Append($"<Form.Item label='{component.Title}' name='{component.Name}' ");
			if (component.Required)
			{
				strResult.Append("rules={[{ required: true, message: '" + component.Message + "' }]}");
			}
			strResult.Append(" >");
			strResult.Append($"<{WidgetTypeName} placeholder='{component.Placeholder}' mode='{component.Mode}' name='{component.Name}' options={{{datasourceName}}}");
			strResult.Append(" />");
			strResult.Append($"</Form.Item>");

			return strResult.ToString();
		}

		private (List<string> VariableList, List<string> FunctionList) GenerateDatasource(Component component, DatasourceConfig datasourceConfig)
		{
			if (!component.DatasourceId.HasValue)
			{
				return (new List<string>(), new List<string>());
			}

			Engine.Configure(c =>
			{
				c.TagPrefix = "@{";
				c.TagSuffix = "}";
			});

			var variableList = new List<string>() { $" const [{datasourceConfig.Name.CapitalizeLower()},set{datasourceConfig.Name}] = useState<any[]>();" };
			var env = ServiceLocator.Resolve<IWebHostEnvironment>();
			var datasourceTplPath = @$"{env.ContentRootPath}\\tpl\\front\\selectDatasource.tpl";
			var templateFile = Engine.LoadTemplate(datasourceTplPath);
			templateFile.Set("config", datasourceConfig);
			return (variableList, new List<string>() { templateFile.Render() });
		}
	}
}
